//
//  main.m
//  C04_ 数组,宏定义
//
//  Created by dllo on 15/11/20.
//  Copyright © 2015年 dllo. All rights reserved.
//

#import <Foundation/Foundation.h>

/** 定义宏 */

#define PI 3.1415/*宏*/
/** 带参数的宏 */
#define MUL(A,B) (A * B)/**< 计算两个数的积的宏 */
int main(int argc, const char * argv[]) {

#pragma mark 知识点1 一维数组
    {
#if 0
        /** 定义一个数组*/
        
        /** 
         * array: 数组名
         * int [5]: 数组类型
         * int : 数组中的元素类型
         * [] : 元素的个数
         */
        
        /** 1. 整型数组 (数组元素都是整型) */
        int array[5] = {3, 4, 5, 6, 7 ,8};
        /** 2. 浮点型数组 (数组元素都是浮点型) */
        float array2[5] = {4.4, 3.14, 5.28};
        /** 3. 字符型数组 (数组元素都是字符型) */
        char array3[5] = {'a', 'b'};
        /** 4. 指针数组 (数组元素都是指针) */
        
        
        /** 数组元素的访问 
         * 通过下标的形式 : array [下标]
         * 下标是从0开始的
         */
        int array4[5] = {3, 4, 5, 6, 1};
        printf("%d \n",array4[0]);
        printf("%d \n",array4[1]);
        printf("%d \n",array4[3]);
        /** 数组元素赋值 */
//        array4[0] = 100;
        printf("%d\n", array4[0]);
        
        /** 使用for循环 遍历数组(打印每个元素) */
        for (int i = 0; i < 5; i ++) {
            printf("%d \n",array4[i]);
        }
        
#endif
    }
#pragma mark 课堂练习
    {
#if 0
        /** 1. 输入5个数, 计算找出最大值和所有元素的和 */
        int array[5] = {0};
        printf("请输入五个整数:");
        /** 遍历数组,输入 */
        for (int i = 0; i < 5; i++) {
            scanf("%d", &array[i]);
        
        }
        /** 遍历数组 找出最大值,和计算所有元素的和 */
        int max = 0;
        int sum = 0;
        for (int i = 0; i< 5; i++) {
            /** 找出最大值 */
            if (max < array[i]) {
                max = array[i];
            }
            /** 所有元素的和 */
            sum += array[i];
        }
        /** 输出结果*/
        printf("sum = %d, max = %d\n", sum, max);
        
#endif
        
        /**
         * 2. 定义一个具有 20个元素 的 整型数组，每个元素的 取值范围是30-70之间，求 数组元素的和
         */
#if 0
        int array[20]= {};
        int sum = 0;
        
        for (int a = 0; a < 20; a++) {
            array[a] = arc4random()%(70-30+1)+30;
            sum += array[a];
        }
        printf("sum = %d\n", sum);
        
#endif
        
#if 0
        /**
         * 3.复制一个数组，即两个数组 容量一样，把其中一个数组中的元素 复制 到另外一个数组中
         */
        int array[5] = {3, 4, 2, 5, 6};
        int array1[5] = {};
        for (int i = 0; i < 5; i++) {
            <#statements#>
        }
        
        
        
#endif
        
#if 0
        /**
         * 5.整形数组的长度20,随机数范围35 - 90, 找到数组中最大的元素的值和它所对应的下标
         */
        int array[20]={0};
        
        for (int i = 0; i < 20; i++) {
            array[i]=arc4random()%(90-35+1)+35;
            
        }
        /** 遍历数组 找最大值 以及下标 */
        int max = 0;
        int index = 0;
        for (int i = 0; i < 20; i++) {
            if (max< array[i]) {
                max = array[i];
                index = i;/* 最大值下标*/
            }
        }
        printf("max = %d, index = %d\n", max, index);
        
        
#endif
        
    }
#pragma mark 知识点2 数组排序(冒泡排序)
    {
#if 0
        /**
         *（1）、定义一个6个整型的数组，让奇偶位元素的值交换。
         *（2）、定义一个6个整型的数组，如果奇位比偶位元素的值大，则交换两个数的值。
         *（3）、定义一个6个整型的数组，通过俩俩比较把最大值放在后面，实现最大值放在最后。
         *（4）、在上题的基础上把倒数第二大的数字放在倒数第二位。（别再原来的for循环上操作，新创建一个for循环）
         *（5）、把第三大的数字放在倒数第三位上。
         *（6）、把第四大的数字放在倒数第三位上。
         *（7）、把第五大的数字放在倒数第三位上。
         *（8）、观察上面的规律，用双层for循环把数组排序。
         */
        /** 1.定义一个6个整型的数组，让奇偶位元素的值交换。*/
        int array[6] = {3, 2, 4, 5, 6, 1};
        int temp = 0;
        for (int i = 0; i < 6; i+=2) {
            temp = array[i];
            array[i] = array[i + 1];
            array[i + 1] = temp;
        }
        for (int i = 0; i < 6; i++) {
            printf("%d ", array[i]);
        }
        
        /** 2. 定义一个6个整型的数组，如果奇位比偶位元素的值大，则交换两个数的值。*/
        for (int i = 0; i < 6; i+=2) {
            if (array[i] > array[i + 1]) {
                temp = array[i];
                array[i] = array[i + 1];
                array[i + 1]=temp;
            }
        }
        for (int i = 0; i < 6; i++) {
            printf("%d ", array[i]);
        }
        printf("\n");
        
#endif
#if 0
        /** 第一次: 定义一个6个整型的数组，通过俩俩比较把最大值放在后面，实现最大值放在最后。*/
        int array[6] = {3, 2, 6, 4, 5, 1};
        int temp = 0;
        /** 第一次比较5次 */
        for (int i = 0; i < 6-1; i++) {
            if (array[i] > array[i+1]) {
                temp = array[i];
                array[i] = array[i+1];
                array[i+1] = temp;
            }
        }
        /** 第二次比较: 两两比较 ,找出第二大的数,   放在数组倒数第二的位置 */
        
        for (int i = 0; i < 6-2; i ++) {
            if (array[i] > array[i+1]) {
                temp = array[i];
                array[i] = array[i+1];
                array[i+1] = temp;
            }
        }
        /** 第三次*/
        for (int i =0 ; i<6-3; i++) {
            temp = array[i];
            array[i] = array[i+1];
            array[i+1] = temp;
        }
        /** 第四次*/
        for (int i = 0; i < 6-4; i++) {
            temp =array[i];
            array[i] = array[i+1];
            array[i+1]; = temp;
        }
        /** 第五次*/
        for (int i = 0; i<6-5; i++) {
            
            
        }
#endif
        
#if 0
     /** 冒泡排序 */
        int array[6] = {3, 4, 5, 6, 1, 2};
        int temp = 0;
        /** 外层的for循环控制比较的次数*/
        for (int i = 1; i<6-1; i++) {
            /** 内层的for循环控制每次的需要*/
            for (int j = 0; j < 6-1-i; j++) {
                if (array[j] > array[j+1]) {
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
            
            
            }
        
        for (int i = 0; i<6; i++) {
            printf("%d", array[i]);
        }
        
        
        
        
#endif
        
#if 0
        
        int array[6] = {3, 2, 1, 6, 4, 5};
        int temp = 0;
        for (int i = 0; i < 6 - 1; i ++) {
            for (int j = 0; j < 6 - 1 - i; j++) {
                if (array[j]>array[j+1]) {
                    temp = array[j];
                    array[j]= array[j+1];
                    array[j+1]=temp;
                }
            }
        }
        for (int i = 0; i<6; i++) {
            printf("%d ", array[i]);
        }
        printf("\n");

#endif
        
#if 0
        /** 计算数组元素个数 */
        int array[] = {3, 4, 2, 1};
        /** sizeof 计算数组的字节数 */
        printf("%lu\n", sizeof(array));
        int count = sizeof(array) / sizeof(int);
        printf("count = %d\n", count);
        /** 数组的总字节数 除于 第一个元素所占的字节数,就可以得出有几个元素了 */
        int count2 = sizeof(array) / sizeof(array[0]);
        
        printf("count2 = %d\n",count2);
        
        
#endif
        
#if 0
      /** 冒泡排序  优化版 */
     
        int array[] = {3, 5, 2, 6, 1, 4};
        
        int count = sizeof(array) / sizeof(array[0]);
        
        int temp = 0;
        int flag = 1; /**< 1表示数组无序 */
        
        for (int i = 0; i < count - 1 && 1 == flag; i++) {
            flag = 0;/* 0表示有序 假设是有序*/
            for (int j = 0; j < count - 1 - i; j++) {
                
                if (array[j] > array[j + 1]) {
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1 ] = temp;
                    flag = 1;/* 发生交换,说明是无序,将flag赋值为1 */
                }
                
            }
            
        }
        
        for (int i = 0; i < count; i++) {
            printf("%d ", array[i]);
        }
        
        
#endif
        
    }
#pragma mark 课堂练习
    {
        
        
    }
#pragma mark 知识点3 字符数组(字符串)
    {
#if 0
        /** 字符数组是用于存放字符变量的数组,数组元素是字符类型(char)
        * 字符数组属于一维数组, 定义方式与普通一维数组相似,
        *
        */
        /** 定义字符数组 */
        char string[5] = {'a', 'b', 'c', 'd', 'e'};
        /**  字符数组所占的字节数 */
        printf("%lu\n", sizeof(string));
        
        char string2[10] = {'i', 'o', 's'};
        printf("%lu\n", sizeof(string2));
        
        /** 注意  双引号定义的字符数组,再数组的最后一位   系统会自动添加一个\0  所以  整个字符数组占的字节会多出1个字节 */
        char string3[] = "iphone";
        printf("%lu\n", sizeof(string3));

  
        
        
#endif
        
    }
#pragma mark 课堂练习
    
    {
#if 0      
        /** 字符串常用函数 */
        char string4[] = "iphone6splus";
        /** 函数1 strlen()   计算字符串长度 */
        printf("长度:%lu\n", strlen(string4));

        printf("字节数:%lu\n", sizeof(string4));

        /**  查找字符串中的空格数: 例如 "I love iOS , i want an iphone6s" */
        char str[] = "I love iOS , i want an iphone6s";
        int count = 0;
        int i = 0;
        while (str[i] != '\0') {
            if (str[i] == ' ') {
                count++;
            }
            i++;
        }
        printf("空格数:%d\n", count);
        
#endif
        
#if 0
        /** 函数2 strcpy 字符串拷贝*/
     
        char string[] = "iphone";
        char string2[100] = "iOS";
        strcpy(string2/*目标*/, string/*源*/);
        /** %s,是输出字符串,  注意  直到遇到\0,停止输出 */
        printf("string:%s\n", string);
        printf("string2:%s\n", string2);

        printf("over");
       
        
#endif
        
#if 0
        /** 函数3 拼接 strcat */
        
        char string[] = "iphone";
        char string2[20] = "iOS";
        
        strcat(string2, string);/* string拼接在string2的后面 */
        printf("string2:%s\n",string2);
        printf("string:%s\n",string);
#endif
#if 0
       /** 函数4 字符串比较 strcmp */
        /* strcmp 是两个字符串从第一字节开始比较,比较的值为两个字符的ACCII码值之差 当比较值不为0时,停止比较,根据值的正或者负判断大小 */
        char string[] = "abc";
        char string2[] = "arc";
        /* 函数有一个返回值  通过返回值判断比较的结果*/
       int result = strcmp(string2, string);
        
        printf("result:%d\n", result);

#endif
    }
#pragma mark 知识点4 宏定义
    {
#if 0
        /** 宏定义通常是在韩式的外边按定义的 , 详见main函数的上边宏部分*/
        printf("%f\n", PI);
        MUL(3, 5);
        printf("%d\n", MUL(3, 5));
#endif
    }
    
    
    
    
    
    
    return 0;
}
